#include "socket.hpp"
#include "game.hpp"
#include <fcntl.h>
#include <queue>
#include <pthread.h>

void Usage(std::string proc)
{
    std::cout << "Usage: " << proc << "ip port" << std::endl;
}

void setNonBlock(int sock)
{
    int old = fcntl(sock, F_GETFL);
    if (old < 0)
    {
        std::cout << "fcntl error" << std::endl;
        return;
    }
    fcntl(sock, F_SETFL, old | O_NONBLOCK);
}

void* startGame(void* arg)
{
    std::cout << "game start" << std::endl;
    // 线程分离
    pthread_detach(pthread_self());
    Game* g = (Game*)arg;
    // 设置非阻塞
    for (int i = 0;i < g->socks.size();i++)
    {
        setNonBlock(g->socks[i]);
    }
    for (;;)
    {
        for (int i = 0;i < g->socks.size();i++)
        {
            memset(g->data, '\0', NUM);
            int n = read(g->socks[i], g->data, NUM);
            if (n > 0)
            {
                std::cout << g->data << std::endl;
                bool ret = g->playChess(g->socks[i], g->data);
                // game over
                if (ret == false)
                {
                    std::cout << "game over" << std::endl;
                    delete g;
                    return NULL;
                }
            }
        }
    }
}

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(-1);
    }
    // 创建socket
    int listen_sock = Sock::Socket();
    int optval = 1;
    // 设置端口重用
    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    // 绑定
    Sock::Bind(listen_sock, atoi(argv[1]));
    // 监听
    Sock::Listen(listen_sock);
    // 接收socket
    char data[NUM] = {0};
    int count = 0;
    Game* g = NULL;
    for (;;)
    {
        int sock = Sock::Accept(listen_sock);
        memset(data, '\0', NUM);
        int n = read(sock, data, NUM);
        std::cout << "data: " << data << std::endl;
        if (n > 0)
        {
            if (count % 2 == 0)
            {
                g = new Game();
            }
            g->socks.push_back(sock);
            count++;
            // 获取颜色
            g->getColor(sock);
            if (count % 2 == 0)
            {
                pthread_t tid;
                pthread_create(&tid, NULL, startGame, (void*)g);
            }
        }
    }
    
    return 0;
}